﻿using System;
using System.Collections.Generic;
using System.Threading;

namespace YArchitech.Controls.ImgListView
{
	internal class ImageListViewItemCacheManager : IDisposable
	{
		private bool Stopping
		{
			get
			{
				object obj = this.lockObject;
				bool result;
				lock (obj)
				{
					result = this.stopping;
				}
				return result;
			}
		}

		public bool Stopped
		{
			get
			{
				object obj = this.lockObject;
				bool result;
				lock (obj)
				{
					result = this.stopped;
				}
				return result;
			}
		}

		public ImageListViewItemCacheManager(ImageListView owner)
		{
			this.lockObject = new object();
			this.mImageListView = owner;
			this.toCache = new Queue<ImageListViewItemCacheManager.CacheItem>();
			this.editCache = new Dictionary<Guid, bool>();
			this.mThread = new Thread(new ThreadStart(this.DoWork));
			this.mThread.IsBackground = true;
			this.stopping = false;
			this.stopped = false;
			this.disposed = false;
			this.mThread.Start();
			while (!this.mThread.IsAlive)
			{
			}
		}

		public void BeginItemEdit(Guid guid)
		{
			object obj = this.lockObject;
			lock (obj)
			{
				if (!this.editCache.ContainsKey(guid))
				{
					this.editCache.Add(guid, false);
				}
			}
		}

		public void EndItemEdit(Guid guid)
		{
			object obj = this.lockObject;
			lock (obj)
			{
				if (this.editCache.ContainsKey(guid))
				{
					this.editCache.Remove(guid);
				}
			}
		}

		public void Add(ImageListViewItem item)
		{
			object obj = this.lockObject;
			lock (obj)
			{
				this.toCache.Enqueue(new ImageListViewItemCacheManager.CacheItem(item));
				Monitor.Pulse(this.lockObject);
			}
		}

		public void Stop()
		{
			object obj = this.lockObject;
			lock (obj)
			{
				if (!this.stopping)
				{
					this.stopping = true;
					Monitor.Pulse(this.lockObject);
				}
			}
		}

		public void Dispose()
		{
			if (!this.disposed)
			{
				this.disposed = true;
			}
		}

		private void DoWork()
		{
			object obj;
			while (!this.Stopping)
			{
				ImageListViewItemCacheManager.CacheItem cacheItem = null;
				obj = this.lockObject;
				lock (obj)
				{
					if (this.toCache.Count == 0)
					{
						Monitor.Wait(this.lockObject);
					}
					if (this.toCache.Count != 0)
					{
						cacheItem = this.toCache.Dequeue();
						if (this.editCache.ContainsKey(cacheItem.Item.Guid))
						{
							cacheItem = null;
						}
					}
				}
				if (cacheItem != null)
				{
					if (cacheItem.IsVirtualItem)
					{
						if (this.mImageListView != null && this.mImageListView.IsHandleCreated && !this.mImageListView.IsDisposed)
						{
							VirtualItemDetailsEventArgs virtualItemDetailsEventArgs = new VirtualItemDetailsEventArgs(cacheItem.VirtualItemKey);
							this.mImageListView.RetrieveVirtualItemDetailsInternal(virtualItemDetailsEventArgs);
							this.mImageListView.Invoke(new UpdateVirtualItemDetailsDelegateInternal(this.mImageListView.UpdateItemDetailsInternal), new object[]
							{
								cacheItem.Item,
								virtualItemDetailsEventArgs
							});
						}
					}
					else
					{
						Utility.ShellImageFileInfo shellImageFileInfo = new Utility.ShellImageFileInfo(cacheItem.FileName);
						if (!this.Stopping)
						{
							try
							{
								if (this.mImageListView != null && this.mImageListView.IsHandleCreated && !this.mImageListView.IsDisposed)
								{
									this.mImageListView.Invoke(new UpdateItemDetailsDelegateInternal(this.mImageListView.UpdateItemDetailsInternal), new object[]
									{
										cacheItem.Item,
										shellImageFileInfo
									});
								}
							}
							catch (ObjectDisposedException)
							{
								if (!this.Stopping)
								{
									throw;
								}
							}
							catch (Autodesk.Revit.Exceptions.InvalidOperationException)
							{
								if (!this.Stopping)
								{
									throw;
								}
							}
						}
					}
				}
			}
			obj = this.lockObject;
			lock (obj)
			{
				this.stopped = true;
			}
		}

		private readonly object lockObject;

		private ImageListView mImageListView;

		private Thread mThread;

		private Queue<ImageListViewItemCacheManager.CacheItem> toCache;

		private Dictionary<Guid, bool> editCache;

		private volatile bool stopping;

		private bool stopped;

		private bool disposed;

		private class CacheItem
		{
			public ImageListViewItem Item
			{
				get
				{
					return this.mItem;
				}
			}

			public string FileName
			{
				get
				{
					return this.mFileName;
				}
			}

			public bool IsVirtualItem
			{
				get
				{
					return this.mIsVirtualItem;
				}
			}

			public object VirtualItemKey
			{
				get
				{
					return this.mVirtualItemKey;
				}
			}

			public CacheItem(ImageListViewItem item)
			{
				this.mItem = item;
				this.mIsVirtualItem = item.isVirtualItem;
				this.mVirtualItemKey = item.mVirtualItemKey;
				this.mFileName = item.FileName;
			}

			private ImageListViewItem mItem;

			private string mFileName;

			private bool mIsVirtualItem;

			private object mVirtualItemKey;
		}
	}
}
